package cn.scnu.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.scnu.common.model.PaginationData;
import cn.scnu.common.model.ResponseResult;
import cn.scnu.component.exception.Asserts;
import cn.scnu.model.dto.*;
import cn.scnu.model.enums.QueryOperationEnum;
import cn.scnu.model.enums.TableNameEnum;
import cn.scnu.model.query.FuzzySearchQueryParam;
import cn.scnu.model.query.GetDataQueryParam;
import cn.scnu.model.query.MonthCountQueryParam;
import cn.scnu.model.query.ProjectResultQueryParam;
import cn.scnu.service.IProjectAcceptanceService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * 档案数据统计分析
 *
 * @author hqz
 * @className DataAnalysisController
 * @createTime 2024年11月28日 14:44:00
 */
@RestController
@RequestMapping("/dataAnalysis")
@RequiredArgsConstructor
@Slf4j
@Api(tags = "档案数据统计分析")
public class DataAnalysisController {

    private final IProjectAcceptanceService projectAcceptanceService;

    @Value("${file.tableMetaInfo}")
    private String tableMetaInfoFile;

    @ApiOperation(value = "获取需要查询的表名")
    @GetMapping("getTableNames")
    public ResponseResult<TableNameEnum[]> getTableNames() {
        return ResponseResult.success(TableNameEnum.values());
    }


    @ApiOperation(value = "工程成果分页查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "queryParam", value = "查询参数", required = true, dataType = "ProjectResultQueryParam")
    })
    @PostMapping("getProjectResultPage")
    public <T> ResponseResult<PaginationData<T>> getProjectResultPage(@RequestBody ProjectResultQueryParam queryParam) {
        return ResponseResult.success(projectAcceptanceService.getProjectResultPage(queryParam));
    }

    // @ApiOperation(value = "主要功能类型查询，模糊搜索")
    // @ApiImplicitParam(name = "fwgn", value = "功能类型", required = false, dataType = "String")
    // @GetMapping("getFwgnList")
    // public ResponseResult<List<String>> getFwgnList(@RequestParam(required = false) String fwgn) {
    //     return ResponseResult.success(projectAcceptanceService.getFwgnList(fwgn));
    // }
    //
    // @ApiOperation(value = "建筑结构类型")
    // @GetMapping("getJzjgList")
    // public ResponseResult<List<String>> getJzjgList() {
    //     return ResponseResult.success(projectAcceptanceService.getJzjgList());
    // }

    @ApiOperation(value = "根据查询参数获取项目的范围线")
    @PostMapping("getProjectRangeGeometry")
    public ResponseResult<List<BaseKeyValueDTO>> getProjectRangeGeometry(@RequestBody ProjectResultQueryParam queryParam) {
        return ResponseResult.success(projectAcceptanceService.getProjectRangeGeometry(queryParam));
    }

    @ApiOperation(value = "根据所给的字段做模糊搜索")
    @PostMapping("getSearchList")
    public ResponseResult<List<String>> getSearchList(@RequestBody FuzzySearchQueryParam fuzzySearchQueryParam) {
        return ResponseResult.success(projectAcceptanceService.getSearchList(fuzzySearchQueryParam));
    }

    @ApiOperation(value = "获取查询操作列表")
    @GetMapping("getQueryOperationEnumList")
    public ResponseResult<List<EnumTypeDTO>> getQueryOperationEnumList() {
        return ResponseResult.success(QueryOperationEnum.getQueryOperationEnumList());
    }

    @ApiOperation(value = "白云区行政属性查询")
    @GetMapping("getBaiyunAttr")
    @Cacheable("getBaiyunAttr")
    public ResponseResult<List<BaiYunRegionAttrDTO>> getBaiyunAttr() {
        return ResponseResult.success(projectAcceptanceService.getBaiyunAttr());
    }

    @ApiOperation(value = "根据smid获取wkt字符串")
    @GetMapping("getWktForSmid")
    public ResponseResult<String> getWktForSmid(@RequestParam TableNameEnum tableName, @RequestParam Integer smid) {
        return ResponseResult.success(projectAcceptanceService.getWktForSmid(tableName, smid));
    }

    @ApiOperation(value = "根据smid获取数据")
    @PostMapping("getDataForSmid")
    public <T> ResponseResult<T> getDataForSmid(@RequestBody GetDataQueryParam queryParam) {
        return ResponseResult.success(projectAcceptanceService.getDataForSmid(queryParam));
    }

    @ApiOperation(value = "根据smids批量获取wkt字符串")
    @PostMapping("getWktForSmids")
    public ResponseResult<List<String>> getWktForSmids(@RequestParam TableNameEnum tableName, @RequestBody List<Integer> smids) {
        return ResponseResult.success(projectAcceptanceService.getWktForSmids(tableName, smids));
    }

    @ApiOperation(value = "shp文件上传，获取wkt字符串列表")
    @PostMapping("getWktForUploadShp")
    public ResponseResult<List<String>> getWktForUploadShp(MultipartFile shpFile) {
        return ResponseResult.success(projectAcceptanceService.getWktForUploadShp(shpFile));
    }

    @ApiOperation(value = "导出工程成果为excel文件", produces = "application/octet-stream")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "queryParam", value = "查询参数", required = true, dataType = "ProjectResultQueryParam")
    })
    @PostMapping("exportProjectResultExcel")
    public void exportProjectResultExcel(@RequestBody ProjectResultQueryParam queryParam, HttpServletResponse response) {
        projectAcceptanceService.exportProjectResultExcel(queryParam, response);
    }

    @ApiOperation(value = "工程成果指标统计")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "queryParam", value = "查询参数", required = true, dataType = "ProjectResultQueryParam")
    })
    @PostMapping("getProjectResultIndex")
    public ResponseResult<ProjectResultIndexDTO> getProjectResultIndex(@RequestBody ProjectResultQueryParam queryParam) {
        return ResponseResult.success(projectAcceptanceService.getProjectResultIndex(queryParam));
    }

    //-----------------------------------分析图表--------------------------------------------
    @ApiOperation(value = "按镇街分析—按镇街区域划分，统计“总建筑面积”字段，并在图表显示面积和栋数；")
    @PostMapping("getCountByDistrict")
    public ResponseResult<List<BaiYunRegionCountDTO>> getCountByDistrict(@RequestBody ProjectResultQueryParam queryParam) {
        return ResponseResult.success(projectAcceptanceService.getCountByDistrict(queryParam));
    }

    @ApiOperation(value = "按时间分析—按“完成时间”字段分类，统计“总建筑面积”字段，并在图表显示面积；")
    @PostMapping("getMonthCountForZjzmj")
    public ResponseResult<List<ZjzmjMonthDTO>> getMonthCountForZjzmj(@RequestBody MonthCountQueryParam queryParam) {
        return ResponseResult.success(projectAcceptanceService.getMonthCountForZjzmj(queryParam));
    }

    @ApiOperation(value = "按时间分析—按“完成时间”字段分类，并在图表显示栋数；")
    @PostMapping("getMonthCountForDs")
    public ResponseResult<List<DsMonthDTO>> getMonthCountForDs(@RequestBody MonthCountQueryParam queryParam) {
        return ResponseResult.success(projectAcceptanceService.getMonthCountForDs(queryParam));
    }

    @ApiOperation(value = "按功能分析—按“主要功能”字段分类，统计“主要功能建筑面积”字段；fwgn字段替换为gnlb")
    @PostMapping("getZygnGroupCount")
    public ResponseResult<List<ZygnGroupCountDTO>> getZygnGroupCount(@RequestBody ProjectResultQueryParam queryParam) {
        return ResponseResult.success(projectAcceptanceService.getZygnGroupCount(queryParam));
    }

    @ApiOperation(value = "按楼高—按“建筑高度”字段分类，统计“总建筑面积”字段，并在图表显示面积和栋数；【建筑高度划分区间：大于24米，小于等于24米】")
    @PostMapping("getZjzmjCountGroupByLg")
    public ResponseResult<List<ZjzmjCountGroupByLgDTO>> getZjzmjCountGroupByLg(@RequestBody ProjectResultQueryParam queryParam) {
        return ResponseResult.success(projectAcceptanceService.getZjzmjCountGroupByLg(queryParam));
    }

    @ApiOperation(value = "按层数—按“地上层数”字段分类，统计“总建筑面积”字段，并在图表显示面积和栋数；   【层数划分区间：1~3层为低层、4~6层为多层、7~9层为中高层、10层及10层以上为高层】")
    @PostMapping("getZjzmjCountGroupByCs")
    public ResponseResult<List<ZjzmjCountGroupByCsDTO>> getZjzmjCountGroupByCs(@RequestBody ProjectResultQueryParam queryParam) {
        return ResponseResult.success(projectAcceptanceService.getZjzmjCountGroupByCs(queryParam));
    }

    @ApiOperation(value = "获取完成时间字段的所有年份")
    @PostMapping("getYearsForWcsj")
    public ResponseResult<List<Integer>> getYearsForWcsj(@RequestBody ProjectResultQueryParam queryParam) {
        return ResponseResult.success(projectAcceptanceService.getYearsForWcsj(queryParam));
    }

    @ApiOperation(value = "表描述信息查询，总平、验收、单体")
    @GetMapping("getTableMetaInfo")
    public ResponseResult<TableMetaInfoDTO> getTableMetaInfo(TableNameEnum tableName) {
        // 1. 读取 JSON 文件
        String jsonStr = FileUtil.readString(tableMetaInfoFile, StandardCharsets.UTF_8);

        // 2. 解析 JSON 数组
        JSONArray jsonArray = JSONUtil.parseArray(jsonStr);

        // 3. 过滤匹配的项
        TableMetaInfoDTO dto = new TableMetaInfoDTO();
        for (Object obj : jsonArray) {
            JSONObject jsonObject = (JSONObject) obj;
            if (tableName.getTableName().equals(jsonObject.getStr("table_name"))) {
                dto.setId(jsonObject.getInt("id"));
                dto.setTableName(tableName);
                dto.setTableMetaInfo(jsonObject.getStr("table_meta_info"));
                break;
            }
        }

        // 4. 返回结果
        return ResponseResult.success(dto);
    }

    @ApiOperation(value = "表描述信息修改，总平、验收、单体")
    @PostMapping("updateTableMetaInfo")
    public ResponseResult<Integer> updateTableMetaInfo(@RequestBody TableMetaInfoDTO tableMetaInfoDTO) {
        // 1. 读取 JSON 文件
        String jsonStr = FileUtil.readString(tableMetaInfoFile, StandardCharsets.UTF_8);

        // 2. 解析 JSON 数组
        JSONArray jsonArray = JSONUtil.parseArray(jsonStr);

        // 3. 更新数据
        boolean updated = false;
        for (Object obj : jsonArray) {
            JSONObject jsonObject = (JSONObject) obj;
            if (tableMetaInfoDTO.getTableName().getTableName().equals(jsonObject.getStr("table_name"))) {
                jsonObject.set("table_meta_info", tableMetaInfoDTO.getTableMetaInfo());
                updated = true;
                break;
            }
        }

        // 如果没有找到匹配的项，可以返回错误信息
        if (!updated) {
            Asserts.fail("未找到匹配的表名");
        }

        // 4. 写回 JSON 文件
        File outputFile = new File(tableMetaInfoFile);
        FileUtil.writeUtf8String(jsonArray.toStringPretty(), outputFile);

        return ResponseResult.success(1);
    }

    @ApiOperation(value = "总平：获取统计面板指标，第一个值：统计字段DKZJZMJ 第二个值：总建筑面积总和 DKZJRMJ 计容建筑面积")
    @PostMapping("getMasterPlanStatistics")
    public ResponseResult<List<Double>> getMasterPlanStatistics(@RequestBody ProjectResultQueryParam queryParam) {
        return ResponseResult.success(projectAcceptanceService.getMasterPlanStatistics(queryParam));
    }

    @ApiOperation(value = "总平：按年月统计总建筑面积和案件数")
    @PostMapping("getMasterPlanMonthStatistics")
    public ResponseResult<List<MasterPlanMonthDTO>> getMasterPlanMonthStatistics(@RequestBody MonthCountQueryParam queryParam) {
        return ResponseResult.success(projectAcceptanceService.getMasterPlanMonthStatistics(queryParam));
    }

    @ApiOperation(value = "总平：按镇街分析—按镇街区域划分，统计“总建筑面积”字段，")
    @PostMapping("getMasterPlanCountByDistrict")
    public ResponseResult<List<MasterPlanDKCountDTO>> getMasterPlanCountByDistrict(@RequestBody ProjectResultQueryParam queryParam) {
        return ResponseResult.success(projectAcceptanceService.getMasterPlanCountByDistrict(queryParam));
    }

    @ApiOperation(value = "总平：机场限高分析，统计sfsjjcxg字段的唯一值及数量")
    @PostMapping("getAirportHeightRestrictionAnalysis")
    public ResponseResult<List<BaseKeyValueDTO<String, Integer>>> getAirportHeightRestrictionAnalysis(@RequestBody ProjectResultQueryParam queryParam) {
        return ResponseResult.success(projectAcceptanceService.getAirportHeightRestrictionAnalysis(queryParam));
    }
}
